package com.example.javaproject;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CustomizedThreadPool extends ThreadPoolExecutor {
    private static final int corePoolSize = 2 * Runtime.getRuntime().availableProcessors();
    private static CustomizedThreadPool threadPool;

    private CustomizedThreadPool() {
        super(corePoolSize, corePoolSize, 30, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(),
//                new ArrayBlockingQueue<Runnable>(64),
                new CustomizedThreadFactory(),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        //添加debug信息
                        System.out.println("thread " + r.getClass().getName() + " was rejected cause too may thread loaded");
                    }
                });

        System.out.println("corePoolSize:" + corePoolSize);
        System.out.println("-------------------------------------------------");
    }


    public static CustomizedThreadPool getInstance() {
        if (threadPool == null) {
            synchronized (CustomizedThreadPool.class) {
                if (threadPool == null) threadPool = new CustomizedThreadPool();
            }
        }
        return threadPool;
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if (t == null && r instanceof Future<?>) {
            try {
                ((Future<?>) r).get();
            } catch (CancellationException ce) {
                t = ce;
            } catch (ExecutionException ee) {
                t = ee.getCause();
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt(); // ignore/reset
            }
        }
        if (t != null) {
            System.out.println("Running task appeared exception! Thread [" + Thread.currentThread().getName() + "], because [" + t.getMessage() + "]\n");
        }
    }
}
